import java.math.BigInteger;

public class Base58 {

    private static final char[] code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
    private static final BigInteger big58 = new BigInteger("58");
    private static final BigInteger big0 = new BigInteger("0");

    public static void main(String[] args) throws Exception {

        BigInteger bigInteger = new BigInteger("1346332323232323232232321111111111111111111111112222222222212121");

        System.out.println(bigInteger);
        String base58 = encode(bigInteger);
        System.out.println(base58);

        BigInteger aBigInteger = decode(base58);
        System.out.println(aBigInteger);
        System.out.println(bigInteger.equals(aBigInteger));

        BigInteger bBigInteger = decode1(base58);
        System.out.println(bBigInteger);
        System.out.println(bigInteger.equals(bBigInteger));
    }


    public static String encode(BigInteger bigInteger) {

        StringBuilder sb = new StringBuilder();
        BigInteger devide = bigInteger;
        do {
            BigInteger[] divideAndRemainder = devide.divideAndRemainder(big58);
            int remainder = divideAndRemainder[1].intValue();
            devide = divideAndRemainder[0];
            sb.append(code_string[remainder]);
        } while (!devide.equals(big0));

        return sb.reverse().toString();
    }

    private static BigInteger decode(String str58) throws Exception {

        BigInteger result = new BigInteger("0");
        BigInteger one = new BigInteger("1");

        char[] chars = str58.toCharArray();
        int length = chars.length;

        for (int i = length - 1; i >= 0; i--) {
            int j = convert(chars[i]);
            result = result.add(BigInteger.valueOf(j).multiply(one));
            one = one.multiply(big58);
        }

        return result;
    }


    public static BigInteger decode1(String str58) throws Exception {

        char[] chars = str58.toCharArray();
        int length = chars.length;

        BigInteger result = BigInteger.valueOf(convert(chars[0]));

        for (int i = 1; i < length; i++) {
            result = result.multiply(big58).add(BigInteger.valueOf(convert(chars[i])));
        }

        return result;
    }


    private static int convert(char x) throws Exception {

        for (int j = 0; j < code_string.length; j++) {
            if (x == code_string[j]) {
                return j;
            }
        }

        throw new Exception("钱包地址中包含非法字符");
    }
}